package com.ovopark.organize.server.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ovopark.api.OpenShopApi;
import com.ovopark.entity.OpenShopDep;
import com.ovopark.organize.common.base.BaseResult;
import com.ovopark.organize.server.mapper.FranchiseesAccurateAddressMapper;
import com.ovopark.organize.server.model.entity.*;
import com.ovopark.organize.server.model.pojo.DepartmentsPojo;
import com.ovopark.organize.server.model.query.JsonResult;
import com.ovopark.organize.server.model.vo.FranchiseeAccurateAddressSaveVo;
import com.ovopark.organize.server.model.vo.FranchiseeContractSaveVo;
import com.ovopark.organize.server.model.vo.RedisVo;
import com.ovopark.organize.server.model.vo.UserVo;
import com.ovopark.organize.server.service.FranchiseesAccurateAddressService;
import com.ovopark.organize.server.service.FranchiseesApprovalAddressService;
import com.ovopark.organize.server.service.FranchiseesRegistrationService;
import com.ovopark.organize.server.util.Md5Encoder;
import com.ovopark.organize.server.util.RedisUtil;
import com.ovopark.organize.server.util.ThreadPoolTaskUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author
 * @Title:
 * @Description: 确址
 * @date 2024/4/11 15:51
 **/
@Service
@Slf4j
public class FranchiseesAccurateAddressServiceImpl extends ServiceImpl<FranchiseesAccurateAddressMapper, FranchiseesAccurateAddress> implements FranchiseesAccurateAddressService {

    @Resource
    private FranchiseesRegistrationService franchiseesRegistrationService;

    @Resource
    private FranchiseesApprovalAddressService franchiseesApprovalAddressService;

    @Resource
    private UserService userService;

    @Resource
    private DepartmentsService departmentsService;

    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private MessageSource messageSource;

    @Resource
    private OpenShopApi openShopApi;


    @Override
    public BaseResult saveAccurateAddress(FranchiseeAccurateAddressSaveVo param,Integer userId,String remoteIp,String platform, Locale locale) {
        FranchiseesAccurateAddress accurateAddress = new FranchiseesAccurateAddress();
        Users user = userService.getUsersById(userId);
        if(user.getGroupId() !=null){
            param.setGroupId(user.getGroupId());
        }

        // 先创建用户基本信息，再绑定 门店关系。

        String createUser = messageSource.getMessage("operation_addShiftGroup_addUser", null, locale);
        String createUserName = messageSource.getMessage("operation_addShiftGroup_addUser_name", null, locale);

        UserVo userVo = new UserVo();
        userVo.setUserName(param.getUserName());
        userVo.setShowName(param.getShowName());
        userVo.setGroupId(param.getGroupId());
        userVo.setFranchiseeType(1);
        if(param.getUserId() == null){
            userVo.setPassword(Md5Encoder.toMd5("888888"));
        }
        userVo.setId(param.getUserId());
        BaseResult userResult = userService.updateUserInfoUser(userVo, user.getId(), user.getGroupId(), "saveAccurateAddress", user.getUserName(), remoteIp, platform, createUser,createUserName);

        Users oldUser = null;
        Integer thisUserId = null;
        if (!userResult.getIsError()) {
            JSONObject oldUserJson = JSONObject.parseObject(JSON.toJSONString(userResult.getData()));
            oldUser = oldUserJson.toJavaObject(Users.class);
            param.setUserId(oldUser.getId());
            thisUserId = oldUser.getId();
        } else {
            log.info("用户创建失败"+JSONObject.toJSONString(param)+"result:"+JSONObject.toJSONString(userResult));
            return  BaseResult.error("404","用户创建失败");
        }
        Boolean isOPen = true;
        String openResult = null;
        DepartmentsPojo shop = new DepartmentsPojo();
        BeanUtils.copyProperties(param, shop);
        shop.setName(param.getDepartmentName());
        shop.setShopId(param.getShopId());
        shop.setGroupId(param.getGroupId());
        shop.setOrganizeId(param.getOrganizeId());
        shop.setDepartmentType(param.getDepartmentType());

        FranchiseesApprovalAddress approvalAddress = franchiseesApprovalAddressService.getById(param.getFranchiseesApprovalAddressId());
        String url = "";
        Integer isUpdatelogo = 0;
        if(approvalAddress !=null){
            shop.setLongitude(approvalAddress.getLongitude());
            shop.setLatitude(approvalAddress.getLatitude());
            shop.setAddress(approvalAddress.getAddress());
            shop.setLocation(approvalAddress.getLocation());
            shop.setStoreArea(approvalAddress.getArea());
            url = "";
            //approvalAddress.getDoorUrl();
            if(StringUtils.isNotEmpty(url)){
                isUpdatelogo = 1;
            }
        }
        JsonResult result = departmentsService.saveDepartment(userId, shop, isUpdatelogo, url,"" , "", null, remoteIp, platform, "saveAccurateAddress");
        HashMap<String, Object> date = result.getData();
      //  log.info("绑定 门店"+JSONObject.toJSONString(result));
        if (CollectionUtils.isEmpty(date)) {
            // 门店绑定失败 用户删除 重新选择门店 绑定
            // 如果当前用户是 此次创建的 则删除
            if(param.getUserId() == null){
                userService.deleteById(thisUserId);
            }
            log.info("门店绑定失败"+JSONObject.toJSONString(param)+"result:"+JSONObject.toJSONString(result));
            return BaseResult.error("405","门店创建失败信息");
        }
        if (date.get("data") != null) {
            Departments dep = (Departments) date.get("data");
            Integer departmentId = dep.getId();
            String redis = RedisVo.getDepartmentById + dep.getId();
            redisUtil.del(redis);
            // 加缓存
            String redisStuatus = RedisVo.getDepIdsCheckOpenStatus + dep.getGroupId() + "Status:" + true + "ValidateStatus" + true + "departmentId:" + departmentId;
            String redisStuatusTwo = RedisVo.getDepIdsCheckOpenStatus + dep.getGroupId() + "Status:" + true + "ValidateStatus" + false + "departmentId:" + departmentId;
            redisUtil.del(redisStuatus);
            redisUtil.del(redisStuatusTwo);

            // 绑定人员 加盟商
            FranchiseeContractSaveVo userSaveVo = new FranchiseeContractSaveVo();
            BeanUtils.copyProperties(userVo, userSaveVo);
            userSaveVo.setFranchiseeType(1);
            userSaveVo.setId(thisUserId);
            userSaveVo.setDepPrivilegeIds(Lists.newArrayList(departmentId));
            userSaveVo.setRoleIds(Lists.newArrayList(Role.ROLE_FRANCHISEE));
            BaseResult userReslut =    userService.updateFranchisee(userSaveVo,user.getUserName(),user.getGroupId(),user.getId(),user.getUserName(),remoteIp,platform,user.getUserName());

          //  log.info("绑定 开店信息"+JSONObject.toJSONString(userReslut));
            // 绑定 开店信息
            if(userReslut.getIsError()){
                // 如果当前用户是 此次创建的 则删除
                //如果门店是此次创建的 则删除
                if(param.getUserId() == null){
                    userService.deleteById(thisUserId);
                }
                if(param.getDepartmentId() == null){
                    departmentsService.deleteShopAndOthers(departmentId,userId);
                }
                  log.info("绑定 开店信息失败"+JSONObject.toJSONString(param)+"result:"+JSONObject.toJSONString(userReslut));
                return BaseResult.error("406","用户门店权限绑定失败");
            }


            accurateAddress.setId(param.getId());
            accurateAddress.setGroupId(param.getGroupId());
            accurateAddress.setCreaterId(userId);
            accurateAddress.setCreateTime(new Date());
            accurateAddress.setDepartmentId(departmentId);
            accurateAddress.setFranchiseesApprovalAddressId(param.getFranchiseesApprovalAddressId());
            accurateAddress.setFranchiseesRegistrationId(param.getFranchiseesRegistrationId());
            accurateAddress.setUserId(thisUserId);
            accurateAddress.setOpeningDate(param.getOpeningDate());
            accurateAddress.setPreparationDate(param.getPreparationDate());
            accurateAddress.setTaskTemplateId(param.getTaskTemplateId());
            accurateAddress.setIsOpenStatus(1);
            accurateAddress.setDepartmentId(departmentId);

            OpenShopDep openShopDep = new OpenShopDep();
            openShopDep.setCreateId(user.getId());
            openShopDep.setDepId(departmentId);
            openShopDep.setOpenTime(param.getOpeningDate());
            openShopDep.setPrepareTime(param.getPreparationDate());
            openShopDep.setDepName(param.getDepartmentName());
            openShopDep.setTemplateId(param.getTaskTemplateId());
            openShopDep.setEnterpriseId(param.getGroupId());

            try {
              openResult =   openShopApi.saveOpenDep(openShopDep);
             log.info("openResult:"+openResult+"openShopDep:"+JSONObject.toJSONString(openShopDep));
                 if(StringUtils.isNotEmpty(openResult) && openResult.contains("ok")){
                 }else {
                     // 开店失败
                     isOPen = false;
                     accurateAddress.setIsOpenStatus(0);
                 }
//
            }catch (Exception e){
                log.error("开店失败"+JSONObject.toJSONString(openShopDep)+"result:"+openResult,e);
             // 开店失败
                isOPen = false;
                accurateAddress.setIsOpenStatus(0);
            }

            save(accurateAddress);

            // 异步处理
            ThreadPoolTaskUtils.getThreadPool().execute(new Runnable() {
                @Override
                public void run() {
                    // 线索  并且设置为 已加盟
                    if(param.getFranchiseesRegistrationId() !=null){
                        FranchiseesRegistration franchiseesRegistration =    franchiseesRegistrationService.findFranchiseesRegistrationById(param.getFranchiseesRegistrationId());
                        if(franchiseesRegistration !=null){
                            franchiseesRegistration.setFollowType(4);
                            franchiseesRegistrationService.saveOrUpdateBean(franchiseesRegistration);
                        }
                        // 如果当前地址 没绑定此线索 则绑定
                        franchiseesApprovalAddressService.addRegistration(param.getGroupId(), param.getFranchiseesApprovalAddressId(), param.getFranchiseesRegistrationId(), userId);
                    }

                    if(approvalAddress !=null){
                        if(accurateAddress.getTaskTemplateId() == null){
                         //   approvalAddress.setIsAccurate(2);
                        }else {
                            approvalAddress.setIsAccurate(1);
                        }
                        approvalAddress.setStatus(1);
                        franchiseesApprovalAddressService.saveOrUpdateAddress(approvalAddress);
                    }
                }
            });

        }

        if(!isOPen){
            String mesg = "开店失败:"+openResult;
            log.info("开店失败"+JSONObject.toJSONString(param)+"result:"+openResult);
            return BaseResult.error("407",mesg);
        }
        return BaseResult.success(accurateAddress);
    }

    @Override
    public Map<Integer, Map<Integer, FranchiseesAccurateAddress>> getFranchiseesAccurateAddressByRegistrationIds(List<Integer> franchiseesRegistrationIds, Integer groupId, Integer addressId) {
        LambdaQueryWrapper<FranchiseesAccurateAddress> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(FranchiseesAccurateAddress::getFranchiseesRegistrationId, franchiseesRegistrationIds);
        queryWrapper.eq(FranchiseesAccurateAddress::getGroupId, groupId);
        if(addressId !=null){
            queryWrapper.eq(FranchiseesAccurateAddress::getFranchiseesApprovalAddressId, addressId);
        }
        List<FranchiseesAccurateAddress> accurateAddresses = list(queryWrapper);
        if(CollectionUtils.isNotEmpty(accurateAddresses)){
            Map<Integer, Map<Integer, FranchiseesAccurateAddress>> accurateAddressMap = new HashMap<>();
            Map<Integer, List<FranchiseesAccurateAddress>> accurateAddressMap1 = accurateAddresses.stream().collect(Collectors.groupingBy(FranchiseesAccurateAddress::getFranchiseesRegistrationId));
            accurateAddressMap1.forEach((k,v)->{
                Map<Integer, FranchiseesAccurateAddress> accurateAddressMap2 = v.stream().collect(Collectors.toMap(FranchiseesAccurateAddress::getFranchiseesApprovalAddressId, a -> a));
                accurateAddressMap.put(k,accurateAddressMap2);
            });
            return accurateAddressMap;
        }

        return new HashMap<>();
    }

    @Override
    public Map<Integer, FranchiseesAccurateAddress> getFranchiseesAccurateAddressUserByRegistrationIds(List<Integer> franchiseesRegistrationIds, Integer groupId, Integer addressId) {
        LambdaQueryWrapper<FranchiseesAccurateAddress> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(FranchiseesAccurateAddress::getFranchiseesRegistrationId, franchiseesRegistrationIds);
        queryWrapper.eq(FranchiseesAccurateAddress::getGroupId, groupId);
        if(addressId !=null){
            queryWrapper.eq(FranchiseesAccurateAddress::getFranchiseesApprovalAddressId, addressId);
        }
        List<FranchiseesAccurateAddress> accurateAddresses = list(queryWrapper);
        if(CollectionUtils.isNotEmpty(accurateAddresses)){
            Map<Integer, FranchiseesAccurateAddress> accurateAddressMap = accurateAddresses.stream().filter(o->o.getUserId() !=null).collect(Collectors.toMap(FranchiseesAccurateAddress::getFranchiseesRegistrationId, a -> a));
            return accurateAddressMap;
        }
        return null;
    }


}
